# SVN

  • SVN(Subversion),集中式版本控制系统,CVS(Concurrent Versions System)的替代产物
  • 下载仓库资源 checkout、修改/提交 commit 仓库资源、同步 update 仓库资源

# Git

# Git 常用命令

Git基本操作
  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库

# 用户配置

  • git config --global user.name "Your Name":全局配置用户名
  • git config --global user.email "email@example.com":全局配置邮箱
  • git config --global alias.plm 'pull origin master':设置别名
  • git config --global core.editor notepad:设置默认编辑器
  • git config --local core.sshCommand "ssh -i /path/to/private/private_ssh_key":指定本仓库使用的 SSH 私钥
  • 配置级别,本地级别优先于所有其他级别,全局级别优先于系统级别,git config --list
    1. 本地配置(--local):默认,高优先级,只影响本仓库,保存目录 .git/config,git config --list --local
    2. 全局配置(--global):中优先级,影响到所有当前用户的 git 仓库,保存目录 ~/.gitconfig,git config --list --global
    3. 系统级(--system):低优先级,影响到全系统的 git 仓库,保存目录 /etc/gitconfig,git config --list --system

# 基本操作

  • git init:在当前目录下初始化仓库(--bare,纯版本库,没有工作目录)
  • git add readme.txt:把文件添加到暂存区(同时文件被跟踪)
  • git commit -m "wrote a readme file":提交到本地仓库
  • git commit --amend -m "new commit message":将暂存区中的文件提交以修改最后一次提交的内容,或修改最后一次提交的提交说明
  • git log --pretty=oneline:查看提交日志
  • git reflog:查看提交日志(包括已经撤销的提交,即 HEAD 移动的记录)
  • git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
  • git status:查看当前版本库的状态
  • git diff readme.txt:查看差异
  • git checkout -- readme.txt:撤销 readme.txt 文件在工作区的全部修改(对比暂存区或版本库)
  • git reset --soft <commit id>:移动 HEAD 到指定提交
  • git reset --mixed <commit id>:移动 HEAD 到指定提交,并重置索引
  • git reset --hard HEAD^:回退到上一个版本
  • git reset --hard <commit id>:回退到指定版本
  • git revert HEAD:撤销最近一次提交
  • git revert HEAD~1:撤销上上次的提交,注意:数字从 0 开始
  • git revert <commit id>:撤销指定的提交,撤销也会作为一次提交进行保存
  • git revert -m 1 <commit id>:如果要回滚的提交是 merge 后得到(父节点有 2 个),可以通过 -m 1 指定需要被保留下来的父节点(-m 选项接收的参数是一个数字,数字取值为 1 和 2)(Often this will be parent number one, for example if you were on master and did git merge unwanted and then decided to revert the merge of unwanted. The first parent would be your pre-merge master branch and the second parent would be the tip of unwanted.)
  • git revert 是用一次新的提交来回滚之前的提交,git reset 是直接删除指定的提交
  • git rm --cached **/*.log:已经 push 过的文件,想从 git 远程库中删除,并在以后的提交中忽略,但在本地保留该文件
  • git update-index --assume-unchanged config/config.xml:已经 push 过的文件,想在以后的提交时忽略此文件,即使本地已经修改过,且不删除 git 远程库中相应文件

git-status

  • 三棵树

    1. HEAD:当前分支引用的指针,总是指向该分支上的最后一次提交,这表示 HEAD 将是下一次提交的父结点
    2. 暂存区(Index):预期的下一次提交(暂存区)的快照
    3. 工作目录:相当于沙盒,在将修改提交到暂存区并记录到历史之前,可以随意更改
    git-workflow

# 分支操作

  • git branch:查看本地分支列表
  • git branch -r:查看远程分支列表
  • git branch <branch>:创建分支
  • git branch -d <branch>:删除分支
  • git branch -D <branch>:强制删除分支
  • git branch -u origin/<branch>:设置本地分支跟踪的远程分支(上游分支)或 git branch --set-upstream-to origin/<branch>
  • git branch --unset-upstream:取消跟踪远程分支(上游分支)
  • git checkout <branch>:切换分支(切换分支前要先提交改动或使用 git stash 保存当前的操作)
  • git checkout -b <branch> -t origin/<branch>:创建 + 切换分支,(-t 设置跟踪的远程分支,可省略)
  • git merge <branch>:合并某分支的所有变更到当前分支
  • git merge --squash <branch>:合并某分支的所有变更到当前分支,但不提交、不移动 HEAD
  • git merge-base <branch1> <branch2>:在两次提交之间找出最佳的公共祖先,用于三向合并
  • git cherry-pick <commit id>, <commit id>:获得在某个提交中引入的变更,然后尝试将作为一个新的提交引入到当前分支上
  • git rebase -i [startpoint] [endpoint] --onto [branchName]:交互式变基,对提交进行分割、合并或者重排序,[startpoint] [endpoint] 指定了一个编辑区间,如果不指定 [endpoint],则该区间的终点默认是当前分支 HEAD 所指向的 commit(注:该区间指定的是一个前开后闭的区间),--onto 指定基底分支。在正在 rebase 的每个提交上可以执行以下动作:
    • pick:保留该提交(缩写:p)
    • reword:保留该提交,但修改该提交的注释(缩写:r)
    • edit:保留该提交,但停下来修改该提交(不仅仅修改注释)(缩写:e)
    • squash:将该提交和前一个提交合并(缩写:s)
    • fixup:将该提交和前一个提交合并,但不要保留该提交的注释信息(缩写:f)
    • exec:执行 shell 命令(缩写:x)
    • drop:丢弃该提交(缩写:d)

# 存储操作

  • git stash save some_msg:保存当前分支所有没有提交的操作
  • git stash list:查看保存的操作
  • git stash pop stash@{num}:恢复某一操作,并把这条 stash 记录删除
  • git stash clear:清空保存的所有操作

# 标签

  • git tag:列出已有的标签
  • git tag v1.0:基于最新提交创建标签
  • git tag -a v1.2 9fceb02:对指定的提交创建标签
  • git checkout v1.0:切换到某个 tag

# 工作区 (opens new window)

  • 一个 git 仓库可以支持多个工作区,允许同时切换到多个分支。 通过 git worktree add,一个新的工作区与仓库相关联,同时还有额外的元数据,以区分该工作区与同一仓库中的其他工作区。 工作区目录树,连同这些元数据,被称为“工作区”。
  • git worktree add <path> -b <new-branch> origin/<branch>
  • git worktree list
  • git worktree remove [-f] <worktree>
  • git worktree prune

# 子模块 (opens new window)

  • 子模块允许将一个 Git 仓库作为另一个 Git 仓库的子目录。它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。
  • git submodule

# 远程操作

  1. 创建 SSH Key:ssh-keygen -t rsa -C "youremail@example.com"
  2. 在 GitLab 上添加的 SSH Key
  3. 添加远程仓库并命名为 origin:git remote add origin git@192.168.113.47:sdky/learngit.git(可添加多个),或者克隆远程仓库作为本地仓库:git clone git@192.168.113.47:sdky/learngit.git learngit
  4. 查看远程仓库:git remote -v
  5. 获取远程仓库的提交历史:git fetch origin
  6. 把远程仓库最新的内容更新到本地仓库:git pull origin master(git pull = git fetch + git merge)
  7. 把本地仓库的 master 分支内容推送到远程仓库 origin 的 master 分支:
    git push origin master
    git push -u origin master-u 关联两个分支
    git push -f origin master(-f 强制推送)
    git push origin master:master

push.default 在 Git 2.0 版本后的默认值为 simple,即:在中央仓库工作流程模式下,拒绝推送到上游与本地分支名字不同的分支,也就是只有本地分支名和上游分支名字一致才可以推送,且只会推送本地当前分支

Git常用命令

# 传输协议 (opens new window)

  • Git 可以使用四种不同的协议来传输资料:本地协议(Local),HTTP 协议,SSH(Secure Shell)协议及 Git 协议。
  • 其中,本地协议由于目前大都是进行远程开发和共享代码所以一般不常用,而 Git 协议由于缺乏授权机制且较难架设所以也不常用。
  • 使用 SSH 协议时,需要先在本地生成 SSH 密钥对再把公钥上传到服务器,SSH 密钥的默认存储目录是 <USER_HOME_DIR>/.ssh/
  • 使用 HTTP 协议时,需要验证用户名/密码(可以选择使用凭证存储工具,比如 macOS 的 Keychain 或者 Windows 的凭据管理器

# 帮助命令

$ git help
使用:git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

这些是在各种情况下使用的通用Git命令:

start a working area (参见命令: git help tutorial)
   clone      将存储库克隆到新目录中
   init       创建一个空的Git存储库或重新初始化一个现有的存储库

work on the current change (参见命令: git help everyday)
   add        将文件内容添加到索引中
   mv         移动或重命名文件、目录或符号链接
   reset      将当前磁头重置为指定状态
   rm         从工作树和索引中删除文件

examine the history and state (参见命令: git help revisions)
   bisect     使用二分查找查找引入错误的提交
   grep       打印与模式匹配的行
   log        显示提交日志
   show       显示各种类型的对象
   status     显示工作树状态

grow, mark and tweak your common history
   branch     列出、创建或删除分支
   checkout   切换分支或还原工作树文件
   commit     记录对存储库的更改
   diff       显示提交、提交和工作树等之间的更改
   merge      将两个或多个开发历史连接在一起
   rebase     在另一个基本提示之上重新应用提交
   tag        创建、列表、删除或验证用GPG签名的标记对象

collaborate (参见命令: git help workflows)
   fetch      从另一个存储库下载对象和引用
   pull       从另一个存储库或本地分支获取并与之集成
   push       更新远程引用和相关对象

'git help -a''git help -g' 列出可用的子命令和一些概念指导。
命令'git help <command>''git help <concept>' 查看特定子命令或概念.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 开发方式

  • 分支开发,主干发布:需要开发一个新功能或者修复一个 Bug 时,从主干拉一个分支进行开发,开发完成且测试通过后,合并回主干,然后从主干进行发布

分支模型

Merge or pull requests are created in a git management application and ask an assigned person to merge two branches. Tools such as GitHub and Bitbucket choose the name pull request since the first manual action would be to pull the feature branch. Tools such as GitLab and Gitorious choose the name merge request since that is the final action that is requested of the assignee. In this article we'll refer to them as merge requests.

  • Pull Request fork 工作流

  • Merge Request merge 工作流

# Git 常用工作流 (opens new window)

Git常用工作流

# GitHub 使用规范流程 (opens new window)

Git使用规范流程

  1. 从主干仓库 GitHub fork 一个项目到自己的 GitHub 仓库
  2. 从自己的 GitHub 仓库 clone 项目到本地仓库自己的分支上
  3. 编写新功能后 git commit 提交到本地仓库
  4. 当远程仓库更新代码后,pull 远程仓库的代码,再通过 rebase 合并到本地分支上
  5. 把本地仓库的代码 push 到自己的 GitHub 仓库,最后再 pull request 到主干仓库

# Git commit 规范

commit message 格式:<type>(<scope>): <subject>,如 fix(DAO): 用户查询缺少 username 属性feat(Controller): 用户查询接口开发

  • type(必须):用于说明 git commit 的类别,只允许使用下面的标识

    • feat:新增功能(feature)
    • fix/to:修复 bug,可以是 QA 发现的 BUG,也可以是研发自己发现的 BUG
    • fix:产生 diff 并自动修复此问题,适合于一次提交直接修复问题
    • to:只产生 diff 不自动修复此问题,适合于多次提交,最终修复问题提交时使用 fix
    • docs:仅仅修改了文档,比如 README、CHANGELOG、CONTRIBUTE 等等
    • style:仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑
    • refactor:代码重构,没有加新功能或者修复 Bug
    • perf:优化相关,比如提升性能、体验
    • test:增加测试用例,包括单元测试、集成测试等
    • chore:改变构建流程,或者增加依赖库、工具等
    • revert:回滚到上一个版本
    • merge:代码合并
    • sync:同步主线或分支的 bug
  • scope(可选):用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同

    • 例如在 Angular,可以是 location、browser、compile、compile、rootScope、ngHref、ngClick、ngView 等
    • 如果修改影响了不止一个 scope,可以使用 * 代替
  • subject(必须):subject 是 commit 目的的简短描述,不超过 50 个字符;建议使用中文,结尾不加句号或其他标点符号

# 自定义 Git

  • 忽略特殊文件:.gitignore 文件,在线浏览:https://github.com/github/gitignore
# 排除所有.开头的隐藏文件:
.*
# 排除所有.class文件:
*.class

# 不排除.gitignore和App.class:
!.gitignore
!App.class
1
2
3
4
5
6
7
8

# Git、Repo、Gerrit 的区别

  1. Git:Git 是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理
  2. Repo (opens new window):Repo 是谷歌用 Python 脚本写的调用 git 的一个脚本,Repo 实现管理多个 git 库。主要是用来下载、管理 Android 项目的软件仓库
  3. Gerrit Code Review (opens new window):基于 Web 的代码评审和项目管理的工具,面向基于 Git 版本控制系统
Updated at: 2024-05-28 22:31:45